// Copyright XXX Inc.  All rights reserved.
// 许可证
// 作者：软件1902冯若轩

// 本软件提供自动生成中小学数学卷子的功能，生成的试卷保存在相应账号的文件夹下。
// 该文件是文件读写及命令行I/O相关处理函数的定义，提供读取命令行字符串、读取文
// 件中的账号和题目、将已出好的题目写入文件的函数

#include "file_and_io.h"

#include <Windows.h>
#include <direct.h>
#include <io.h>

#include <string>

namespace paper {
namespace io {

using std::pair;
using std::string;
using std::to_string;
using std::vector;

// 从命令行中使用scanf函数读取字符串，使用string作为缓冲保存，
// 并重新调整string的大小并返回
string GetString() {
  string temp_string;
  temp_string.resize(1000);  // 1000为缓冲区大小
  scanf("%s", &temp_string[0]);
  temp_string.resize(strlen(temp_string.c_str()));  // 消除多余的部分
  return temp_string;
}

// 用于格式化时间字符串中的月、日、时、分、秒，在其数值小于10时，在
// 前面补0，使得时间字符串中除年外均为两位
string FillZero(string source) {
  if (source.size() < 2) {
    string new_string = "0" + source;
    return new_string;
  }
  return source;
}

// 获取当前时间，并将年与格式化后的月日时分秒用'-'分段隔开，
// 拼接成一个string类型的时间字符串
string GetTimeString() {
  SYSTEMTIME system_time;
  string time_string;
  GetLocalTime(&system_time);
  time_string = to_string(system_time.wYear) + "-" +
                FillZero(to_string(system_time.wMonth)) + "-" +
                FillZero(to_string(system_time.wDay)) + "-" +
                FillZero(to_string(system_time.wHour)) + "-" +
                FillZero(to_string(system_time.wMinute)) + "-" +
                FillZero(to_string(system_time.wSecond));
  return time_string;
}

// 类似于GetString，从命令行中读取账号和密码，分别保存在两个
// string类型字符串中，合并返回
pair<string, string> GetUsernameAndPassword() {
  string temp_username, temp_password;
  temp_username.resize(100);
  temp_password.resize(100);
  scanf("%s %s", &temp_username[0], &temp_password[0]);
  temp_username.resize(strlen(temp_username.c_str()));
  temp_password.resize(strlen(temp_password.c_str()));
  return make_pair(temp_username, temp_password);
}

// 从data文件夹下的users.txt中读取所有用户的账号、密码、类型，
// 使用一个vector容器将其存储并返回
vector<UserAccount> GetAllUser() {
  vector<UserAccount> user_buffer;
  FILE* file_ptr = fopen("data/users.txt", "r");
  string temp_username, temp_password;
  temp_username.resize(100);
  temp_password.resize(100);
  char temp_type;
  UserAccount temp_account;
  while (fscanf(file_ptr, "%s %s %c", &temp_username[0], &temp_password[0],
                &temp_type) != EOF) {
    temp_username.resize(strlen(temp_username.c_str()));
    temp_password.resize(strlen(temp_password.c_str()));
    temp_account.username = temp_username;
    temp_account.password = temp_password;
    temp_account.type = temp_type;
    user_buffer.push_back(temp_account);
    temp_username.resize(100);
    temp_password.resize(100);
  }
  fclose(file_ptr);
  return user_buffer;
}

// 从该用户对应文件夹中读取所有txt文件，从中读取出全部题目，保存在
// 一个vector容器中并返回。读取所有txt文件通过_findfirst和_findnext
// 实现
vector<string> GetQuestionsFromFile(string name) {
  vector<string> all_question;
  struct _finddata_t file_info;
  long handle;
  int symbol_index;  // 隔开序号和题目的"、"在整行中的位置下标
  FILE* file_ptr;
  string path = name + "\\*.txt", file_path = "";
  string temp_question, pure_question;
  temp_question.resize(200);
  // 调用_findfirst()和_findnext()来遍历文件夹中所有.txt后缀的文件
  if ((handle = _findfirst(path.c_str(), &file_info)) == -1L) {
    all_question.clear();
  } else {
    file_path = name + "/" + file_info.name;
    file_ptr = fopen(file_path.c_str(), "r");
    while (fscanf(file_ptr, "%s", &temp_question[0]) != EOF) {
      temp_question.resize(strlen(temp_question.c_str()));
      symbol_index = temp_question.find("、");  // 找到分隔顿号所在位置
      // "、"占2字节，从其后将题目本身与序号分割
      if (symbol_index != temp_question.npos) {
        pure_question = temp_question.substr(symbol_index + 2);
        all_question.push_back(pure_question);
      }
      temp_question.resize(200);
    }
    fclose(file_ptr);
    // 继续遍历直到没有更多.txt文件，执行上述相同操作
    while (!(_findnext(handle, &file_info))) {
      file_path = name + "/" + file_info.name;
      file_ptr = fopen(file_path.c_str(), "r");
      while (fscanf(file_ptr, "%s", &temp_question[0]) != EOF) {
        temp_question.resize(strlen(temp_question.c_str()));
        symbol_index = temp_question.find("、");
        if (symbol_index != temp_question.npos) {
          pure_question = temp_question.substr(symbol_index + 2);
          all_question.push_back(pure_question);
        }
        temp_question.resize(200);
      }
      fclose(file_ptr);
    }
  }
  _findclose(handle);
  return all_question;
}

// 将出好的题目组questions逐个写入txt文件中，文件位于用户名文件夹下，
// 需要首先创建该文件夹再存放，其文件名为时间字符串
void WritePaperIntoFile(string name, vector<string> questions) {
  FILE* file_ptr;
  string path, time_string;
  int i;
  mkdir(name.c_str());  // 创建该用户名文件夹
  time_string = GetTimeString();
  path = name + "/" + time_string + ".txt";
  file_ptr = fopen(path.c_str(), "w");
  for (i = 0; i < questions.size(); i++) {
    // 将序号、分隔顿号和题目合在一起
    fprintf(file_ptr, "%d、%s", i + 1, questions[i].c_str());
    if (i < questions.size() - 1) {
      fprintf(file_ptr, "\n\n");
    }
  }
  fclose(file_ptr);
}
}  // namespace io
}  // namespace paper